@im-nobsidian/core 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -605,6 +605,19 @@ declare class NotionClient {
605
605
  id: string;
606
606
  type: string;
607
607
  }>>;
608
+ getDatabaseSchemaFull(databaseId: string): Promise<Record<string, {
609
+ id: string;
610
+ type: string;
611
+ options?: Array<{
612
+ name: string;
613
+ color?: string;
614
+ }>;
615
+ groups?: Array<{
616
+ name: string;
617
+ color?: string;
618
+ optionIds?: string[];
619
+ }>;
620
+ }>>;
608
621
  queryDatabase(databaseId: string, options?: {
609
622
  startCursor?: string;
610
623
  pageSize?: number;
@@ -1003,11 +1016,13 @@ declare class DatabaseSyncer {
1003
1016
  private readonly pipeline;
1004
1017
  private readonly imageHandler;
1005
1018
  private readonly propertyMapper;
1019
+ private readonly baseFileGenerator;
1006
1020
  constructor(config: Config, stateDb: IStateDB, notionClient: NotionClient, vaultFs: VaultFS, pipeline: ConversionPipeline, imageHandler: ImageHandler);
1007
1021
  pullAll(): Promise<DatabaseSyncResult>;
1008
1022
  pushAll(): Promise<DatabaseSyncResult>;
1009
1023
  pullDatabase(dbConfig: DatabaseSyncConfig): Promise<DatabaseSyncResult>;
1010
1024
  private pullDatabaseViews;
1025
+ private generateBaseFile;
1011
1026
  private pullDatabasePage;
1012
1027
  private pushDatabase;
1013
1028
  }
@@ -1341,6 +1356,40 @@ declare class EntryEditor {
1341
1356
  updateDate(entryPath: string, dateProperty: string, newDate: string): Promise<void>;
1342
1357
  }
1343
1358
 
1359
+ interface BasePropertySchema {
1360
+ readonly id: string;
1361
+ readonly type: string;
1362
+ readonly options?: Array<{
1363
+ name: string;
1364
+ color?: string;
1365
+ }>;
1366
+ readonly groups?: Array<{
1367
+ name: string;
1368
+ color?: string;
1369
+ optionIds?: string[];
1370
+ }>;
1371
+ }
1372
+ interface BaseFileOptions {
1373
+ readonly databaseId: string;
1374
+ readonly databaseName: string;
1375
+ readonly schema: Record<string, BasePropertySchema>;
1376
+ readonly viewsConfig: DatabaseViewsConfig;
1377
+ readonly folderPath: string;
1378
+ }
1379
+ declare class BaseFileGenerator {
1380
+ generate(options: BaseFileOptions): string;
1381
+ private writeFilters;
1382
+ private needsContentCoverFormula;
1383
+ private writeFormulas;
1384
+ private writePropertyDisplayNames;
1385
+ private writeViews;
1386
+ private convertView;
1387
+ private toNoteRef;
1388
+ private resolvePropertyName;
1389
+ private yamlKey;
1390
+ private yamlValue;
1391
+ }
1392
+
1344
1393
  declare function sortEntries(entries: DBEntry[], sorts: NonNullable<ViewConfig["sorts"]>): DBEntry[];
1345
1394
  declare function groupEntries(entries: DBEntry[], groupByProperty: string, options?: {
1346
1395
  sort?: "ascending" | "descending";
@@ -1388,4 +1437,4 @@ interface PipelineOptions {
1388
1437
  }
1389
1438
  declare function createDefaultPipeline(options?: PipelineOptions): ConversionPipeline;
1390
1439
 
1391
- export { BlockConverter, type CalendarEntry, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, type Config, ConfigManager, ConfigSchema, type Conflict, ConflictResolver, type ConflictStrategy, type ConversionContext, type ConversionPath, ConversionPipeline, type ConversionResult, type CoverConfig, type DBEntry, DEFAULT_CONFIG, type DatabaseSyncConfig, type DatabaseSyncResult, DatabaseSyncer, type DatabaseViewsConfig, EmbedResolver, EntryEditor, type FailedOperation, type FileDownloadResult, FileHandler, type FileInfo, type FileRegistryEntry, type FileStatInfo, type FileSystemEntry, type FileType, type FileUploadResult, FileWatcher, type FilterCondition, FrontmatterExtractor, FrontmatterGenerator, type GroupByConfig, type GroupedEntries, HtmlAnnotationStripper, type IStateDB, type ImageDownloadResult, ImageHandler, type ImageReference, InlineDBParser, type LocalChange, LocalImageRestorer, type Logger, type MappingResult, type MappingType, MathNormalizer, MentionToWikilink, type MergeConflictRegion, type MergeResult, NodeVaultFS, type NonMdFileInfo, type NotionBlock, NotionBlockBuilder, NotionClient, type NotionClientOptions, type NotionColor, type NotionPageNode, type NotionRichText, type RichTextItem as NotionRichTextItem, type OperationType, type PageCover, type PageCreationPlan, type PageIcon, type PathFilterConfig, type PreserveMarker, PreserveMarkerCollector, PreserveMarkerInjector, type Processor, type ProcessorInput, type ProcessorMetadata, type ProcessorOutput, type ProgressCallback, type ProgressItem, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, type PropertyOption, type PropertySchema, type PropertyValue, type PullOptions, type PullResult, type PushOptions, type PushResult, type RegisterFileInput, type RemoteChange, type ResolutionChoice, type ResolutionResult, type RichTextSegment, StateDB, type StatusResult, type SyncDirection, type SyncOptions, SyncOrchestrator, type SyncRecord, type SyncResult, type SyncStatus, TreeMapper, UnsupportedBlockStripper, type UpsertSyncRecord, type VaultFS, type ViewConfig, ViewDataProvider, type ViewPropertyConfig, type ViewRenderData, type ViewType, type WatchSyncOptions, WatchSyncService, type WikilinkEntry, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
1440
+ export { BaseFileGenerator, type BaseFileOptions, type BasePropertySchema, BlockConverter, type CalendarEntry, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, type Config, ConfigManager, ConfigSchema, type Conflict, ConflictResolver, type ConflictStrategy, type ConversionContext, type ConversionPath, ConversionPipeline, type ConversionResult, type CoverConfig, type DBEntry, DEFAULT_CONFIG, type DatabaseSyncConfig, type DatabaseSyncResult, DatabaseSyncer, type DatabaseViewsConfig, EmbedResolver, EntryEditor, type FailedOperation, type FileDownloadResult, FileHandler, type FileInfo, type FileRegistryEntry, type FileStatInfo, type FileSystemEntry, type FileType, type FileUploadResult, FileWatcher, type FilterCondition, FrontmatterExtractor, FrontmatterGenerator, type GroupByConfig, type GroupedEntries, HtmlAnnotationStripper, type IStateDB, type ImageDownloadResult, ImageHandler, type ImageReference, InlineDBParser, type LocalChange, LocalImageRestorer, type Logger, type MappingResult, type MappingType, MathNormalizer, MentionToWikilink, type MergeConflictRegion, type MergeResult, NodeVaultFS, type NonMdFileInfo, type NotionBlock, NotionBlockBuilder, NotionClient, type NotionClientOptions, type NotionColor, type NotionPageNode, type NotionRichText, type RichTextItem as NotionRichTextItem, type OperationType, type PageCover, type PageCreationPlan, type PageIcon, type PathFilterConfig, type PreserveMarker, PreserveMarkerCollector, PreserveMarkerInjector, type Processor, type ProcessorInput, type ProcessorMetadata, type ProcessorOutput, type ProgressCallback, type ProgressItem, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, type PropertyOption, type PropertySchema, type PropertyValue, type PullOptions, type PullResult, type PushOptions, type PushResult, type RegisterFileInput, type RemoteChange, type ResolutionChoice, type ResolutionResult, type RichTextSegment, StateDB, type StatusResult, type SyncDirection, type SyncOptions, SyncOrchestrator, type SyncRecord, type SyncResult, type SyncStatus, TreeMapper, UnsupportedBlockStripper, type UpsertSyncRecord, type VaultFS, type ViewConfig, ViewDataProvider, type ViewPropertyConfig, type ViewRenderData, type ViewType, type WatchSyncOptions, WatchSyncService, type WikilinkEntry, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
package/dist/index.js CHANGED
@@ -940,6 +940,39 @@ var NotionClient = class _NotionClient {
940
940
  }
941
941
  return schema;
942
942
  }
943
+ async getDatabaseSchemaFull(databaseId) {
944
+ const db = await this.fetchDatabaseLegacy(databaseId);
945
+ const properties = db.properties;
946
+ if (!properties) return {};
947
+ const schema = {};
948
+ for (const [name, prop] of Object.entries(properties)) {
949
+ const entry = {
950
+ id: prop.id,
951
+ type: prop.type
952
+ };
953
+ if (prop.type === "select" || prop.type === "multi_select") {
954
+ const typeData = prop[prop.type];
955
+ if (typeData?.options) {
956
+ entry.options = typeData.options.map((o) => ({ name: o.name, color: o.color }));
957
+ }
958
+ }
959
+ if (prop.type === "status") {
960
+ const statusData = prop.status;
961
+ if (statusData?.options) {
962
+ entry.options = statusData.options.map((o) => ({ name: o.name, color: o.color }));
963
+ }
964
+ if (statusData?.groups) {
965
+ entry.groups = statusData.groups.map((g) => ({
966
+ name: g.name,
967
+ color: g.color,
968
+ optionIds: g.option_ids
969
+ }));
970
+ }
971
+ }
972
+ schema[name] = entry;
973
+ }
974
+ return schema;
975
+ }
943
976
  async queryDatabase(databaseId, options) {
944
977
  const dsId = await this.getDataSourceId(databaseId);
945
978
  const response = await this.withRateLimit(
@@ -2816,6 +2849,7 @@ ${COLUMN_LIST_END}`;
2816
2849
  let processed = this.extractToggleBlocks(markdown);
2817
2850
  processed = this.extractColumnBlocks(processed);
2818
2851
  processed = this.replaceDividers(processed);
2852
+ processed = processed.replace(/<unknown[^>]*\/>/g, "");
2819
2853
  return processed;
2820
2854
  }
2821
2855
  replaceDividers(markdown) {
@@ -3768,6 +3802,168 @@ function sanitizeFileName(name) {
3768
3802
  return sanitized;
3769
3803
  }
3770
3804
 
3805
+ // src/view/base-file-generator.ts
3806
+ var NOTION_TO_BASES_VIEW = {
3807
+ table: "table",
3808
+ gallery: "cards",
3809
+ list: "list",
3810
+ board: "cards",
3811
+ calendar: null,
3812
+ timeline: null,
3813
+ form: null,
3814
+ chart: null,
3815
+ map: null,
3816
+ dashboard: null
3817
+ };
3818
+ var BaseFileGenerator = class {
3819
+ generate(options) {
3820
+ const lines = [];
3821
+ lines.push(`# Auto-generated by Im-Nobsidian from Notion DB: ${options.databaseName}`);
3822
+ lines.push(`# Database ID: ${options.databaseId}`);
3823
+ lines.push("");
3824
+ this.writeFilters(lines, options.folderPath);
3825
+ this.writeFormulas(lines, options.viewsConfig.views);
3826
+ this.writePropertyDisplayNames(lines, options.schema);
3827
+ this.writeViews(lines, options.viewsConfig.views, options.schema);
3828
+ return lines.join("\n");
3829
+ }
3830
+ writeFilters(lines, folderPath) {
3831
+ lines.push("filters:");
3832
+ lines.push(" and:");
3833
+ lines.push(` - file.inFolder("${folderPath}")`);
3834
+ lines.push("");
3835
+ }
3836
+ needsContentCoverFormula(views) {
3837
+ return views.some(
3838
+ (v) => v.type === "gallery" && v.cover && (v.cover.type === "page_content" || v.cover.type === "page_content_first")
3839
+ );
3840
+ }
3841
+ writeFormulas(lines, views) {
3842
+ if (!this.needsContentCoverFormula(views)) return;
3843
+ lines.push("formulas:");
3844
+ lines.push(" coverImage: file.embeds[0]");
3845
+ lines.push("");
3846
+ }
3847
+ writePropertyDisplayNames(lines, schema) {
3848
+ const entries = Object.entries(schema).filter(([, prop]) => prop.type !== "title");
3849
+ if (entries.length === 0) return;
3850
+ lines.push("properties:");
3851
+ for (const [name] of entries) {
3852
+ lines.push(` ${this.yamlKey(name)}:`);
3853
+ lines.push(` displayName: ${this.yamlValue(name)}`);
3854
+ }
3855
+ lines.push("");
3856
+ }
3857
+ writeViews(lines, views, schema) {
3858
+ const basesViews = views.map((v) => this.convertView(v, schema)).filter((v) => v !== null);
3859
+ if (basesViews.length === 0) {
3860
+ lines.push("views:");
3861
+ lines.push(" - type: table");
3862
+ lines.push(" name: Table");
3863
+ return;
3864
+ }
3865
+ lines.push("views:");
3866
+ for (const view of basesViews) {
3867
+ lines.push(` - type: ${view.type}`);
3868
+ lines.push(` name: ${this.yamlValue(view.name)}`);
3869
+ if (view.order && view.order.length > 0) {
3870
+ lines.push(" order:");
3871
+ for (const col of view.order) {
3872
+ lines.push(` - ${col}`);
3873
+ }
3874
+ }
3875
+ if (view.sort && view.sort.length > 0) {
3876
+ lines.push(" sort:");
3877
+ for (const s of view.sort) {
3878
+ lines.push(` - column: ${s.column}`);
3879
+ lines.push(` direction: ${s.direction}`);
3880
+ }
3881
+ }
3882
+ if (view.groupBy) {
3883
+ lines.push(" groupBy:");
3884
+ lines.push(` property: ${view.groupBy.property}`);
3885
+ if (view.groupBy.direction) {
3886
+ lines.push(` direction: ${view.groupBy.direction}`);
3887
+ }
3888
+ }
3889
+ if (view.image) {
3890
+ lines.push(` image: ${view.image}`);
3891
+ }
3892
+ }
3893
+ }
3894
+ convertView(view, schema) {
3895
+ const basesType = NOTION_TO_BASES_VIEW[view.type];
3896
+ if (!basesType) return null;
3897
+ const result = {
3898
+ type: basesType,
3899
+ name: view.name || view.type
3900
+ };
3901
+ if (view.properties && view.properties.length > 0) {
3902
+ const visible = view.properties.filter((p) => p.visible !== false).map((p) => {
3903
+ const name = p.propertyName ?? this.resolvePropertyName(p.propertyId, schema);
3904
+ return name ? this.toNoteRef(name) : null;
3905
+ }).filter((name) => !!name);
3906
+ if (visible.length > 0) {
3907
+ result.order = ["file.name", ...visible];
3908
+ }
3909
+ }
3910
+ if (view.sorts && view.sorts.length > 0) {
3911
+ result.sort = view.sorts.map((s) => {
3912
+ let column;
3913
+ if (s.property) {
3914
+ const propName = this.resolvePropertyName(s.property, schema) ?? s.property;
3915
+ column = this.toNoteRef(propName);
3916
+ } else if (s.timestamp) {
3917
+ column = s.timestamp === "created_time" ? "file.ctime" : "file.mtime";
3918
+ } else {
3919
+ return null;
3920
+ }
3921
+ return {
3922
+ column,
3923
+ direction: s.direction === "ascending" ? "ASC" : "DESC"
3924
+ };
3925
+ }).filter((s) => s !== null);
3926
+ }
3927
+ if (view.groupBy) {
3928
+ const propName = view.groupBy.propertyName ?? this.resolvePropertyName(view.groupBy.propertyId, schema);
3929
+ if (propName) {
3930
+ result.groupBy = {
3931
+ property: this.toNoteRef(propName),
3932
+ direction: view.groupBy.sort === "ascending" ? "ASC" : view.groupBy.sort === "descending" ? "DESC" : void 0
3933
+ };
3934
+ }
3935
+ }
3936
+ if (view.type === "gallery" && view.cover) {
3937
+ if (view.cover.type === "property" && view.cover.propertyId) {
3938
+ const propName = this.resolvePropertyName(view.cover.propertyId, schema);
3939
+ if (propName) result.image = this.toNoteRef(propName);
3940
+ } else if (view.cover.type === "page_cover") {
3941
+ result.image = "note.cover";
3942
+ } else if (view.cover.type === "page_content" || view.cover.type === "page_content_first") {
3943
+ result.image = "formula.coverImage";
3944
+ }
3945
+ }
3946
+ return result;
3947
+ }
3948
+ toNoteRef(propertyName) {
3949
+ return propertyName;
3950
+ }
3951
+ resolvePropertyName(propertyId, schema) {
3952
+ for (const [name, prop] of Object.entries(schema)) {
3953
+ if (prop.id === propertyId) return name;
3954
+ }
3955
+ return void 0;
3956
+ }
3957
+ yamlKey(key) {
3958
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) return key;
3959
+ return `"${key.replace(/"/g, '\\"')}"`;
3960
+ }
3961
+ yamlValue(value) {
3962
+ if (/^[a-zA-Z0-9_-]+$/.test(value)) return value;
3963
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
3964
+ }
3965
+ };
3966
+
3771
3967
  // src/converter/enhanced-md-converter.ts
3772
3968
  var NOTION_CALLOUT_RE = /^::: callout\n([\s\S]*?)\n:::/gm;
3773
3969
  var NOTION_CALLOUT_TAG_RE = /<callout[^>]*>\n?([\s\S]*?)<\/callout>/g;
@@ -3776,6 +3972,7 @@ var NOTION_PAGE_MENTION_RE = /<mention-page id="([^"]+)">([\s\S]*?)<\/mention-pa
3776
3972
  var NOTION_USER_MENTION_RE = /<mention-user id="[^"]*">([^<]*)<\/mention-user>/g;
3777
3973
  var NOTION_DATE_MENTION_RE = /<mention-date start="([^"]*)"(?: end="([^"]*)")?[^>]*\/>/g;
3778
3974
  var NOTION_UNKNOWN_RE = /<unknown id="([^"]*)"([^>]*)\/>/g;
3975
+ var NOTION_UNKNOWN_URL_RE = /<unknown url="([^"]*)"([^>]*)\/>/g;
3779
3976
  var NOTION_AUDIO_RE = /[\t ]*<audio src="([^"]*)">([\s\S]*?)<\/audio>/g;
3780
3977
  var NOTION_VIDEO_RE = /[\t ]*<video src="([^"]*)">([\s\S]*?)<\/video>/g;
3781
3978
  var NOTION_PDF_RE = /[\t ]*<pdf src="([^"]*)">([\s\S]*?)<\/pdf>/g;
@@ -3887,12 +4084,18 @@ function convertDateMentions(content) {
3887
4084
  });
3888
4085
  }
3889
4086
  function preserveUnknownBlocks(content) {
3890
- return content.replace(NOTION_UNKNOWN_RE, (_match, id, attrs) => {
4087
+ let result = content.replace(NOTION_UNKNOWN_RE, (_match, id, attrs) => {
3891
4088
  const typeMatch = /type="([^"]*)"/.exec(attrs);
3892
4089
  const altMatch = /alt="([^"]*)"/.exec(attrs);
3893
4090
  const blockType = altMatch?.[1] ?? typeMatch?.[1] ?? "unknown";
3894
4091
  return `%%im-nobsidian:unknown:id=${id}&type=${blockType}%%`;
3895
4092
  });
4093
+ result = result.replace(NOTION_UNKNOWN_URL_RE, (_match, url, attrs) => {
4094
+ const altMatch = /alt="([^"]*)"/.exec(attrs);
4095
+ const blockType = altMatch?.[1] ?? "bookmark";
4096
+ return `%%im-nobsidian:unknown:id=${encodeURIComponent(url)}&type=${blockType}%%`;
4097
+ });
4098
+ return result;
3896
4099
  }
3897
4100
  function convertSyncedBlockRef(content) {
3898
4101
  let result = content.replace(
@@ -4170,6 +4373,10 @@ function restoreTabBlocks(content) {
4170
4373
  var OBSIDIAN_UNKNOWN_RE = /%%im-nobsidian:unknown:id=([^&]+)&type=([^%]+)%%/g;
4171
4374
  function restoreUnknownBlocks(content) {
4172
4375
  return content.replace(OBSIDIAN_UNKNOWN_RE, (_match, id, type) => {
4376
+ const decoded = decodeURIComponent(id);
4377
+ if (decoded.startsWith("http")) {
4378
+ return `<unknown url="${decoded}" alt="${type}"/>`;
4379
+ }
4173
4380
  return `<unknown id="${id}" type="${type}"/>`;
4174
4381
  });
4175
4382
  }
@@ -4241,6 +4448,7 @@ var DatabaseSyncer = class {
4241
4448
  pipeline;
4242
4449
  imageHandler;
4243
4450
  propertyMapper = new PropertyMapper();
4451
+ baseFileGenerator = new BaseFileGenerator();
4244
4452
  async pullAll() {
4245
4453
  const databases = this.config.notion.databases;
4246
4454
  if (!databases || databases.length === 0) {
@@ -4295,7 +4503,8 @@ var DatabaseSyncer = class {
4295
4503
  const schema = await this.notionClient.getDatabaseSchema(dbConfig.databaseId);
4296
4504
  this.propertyMapper.loadSchema(schema);
4297
4505
  await this.vaultFs.ensureFolder(dbConfig.localFolder);
4298
- await this.pullDatabaseViews(dbConfig);
4506
+ const viewsConfig = await this.pullDatabaseViews(dbConfig);
4507
+ await this.generateBaseFile(dbConfig, viewsConfig);
4299
4508
  const pages = await this.notionClient.queryAllDatabasePages(
4300
4509
  dbConfig.databaseId,
4301
4510
  dbConfig.pullFilter
@@ -4332,7 +4541,7 @@ var DatabaseSyncer = class {
4332
4541
  try {
4333
4542
  const existing = await this.vaultFs.readFile(configPath);
4334
4543
  const parsed = JSON.parse(existing);
4335
- if (parsed[dbConfig.databaseId]) return;
4544
+ if (parsed[dbConfig.databaseId]) return parsed[dbConfig.databaseId];
4336
4545
  } catch {
4337
4546
  }
4338
4547
  }
@@ -4349,8 +4558,33 @@ var DatabaseSyncer = class {
4349
4558
  getLogger().debug(
4350
4559
  `[DB Sync] \uBDF0 \uC124\uC815 ${viewsConfig.views.length}\uAC1C \uC800\uC7A5: ${dbConfig.databaseId}`
4351
4560
  );
4561
+ return viewsConfig;
4352
4562
  } catch (error) {
4353
4563
  getLogger().warn(`[DB Sync] \uBDF0 \uC124\uC815 Pull \uC2E4\uD328 (\uACC4\uC18D \uC9C4\uD589):`, error);
4564
+ return null;
4565
+ }
4566
+ }
4567
+ async generateBaseFile(dbConfig, viewsConfig) {
4568
+ try {
4569
+ const schemaFull = await this.notionClient.getDatabaseSchemaFull(dbConfig.databaseId);
4570
+ const dbName = viewsConfig?.databaseName || await this.notionClient.getDatabaseTitle(dbConfig.databaseId) || dbConfig.localFolder.split("/").pop() || "Database";
4571
+ const baseContent = this.baseFileGenerator.generate({
4572
+ databaseId: dbConfig.databaseId,
4573
+ databaseName: dbName,
4574
+ schema: schemaFull,
4575
+ viewsConfig: viewsConfig ?? {
4576
+ databaseId: dbConfig.databaseId,
4577
+ databaseName: dbName,
4578
+ lastSynced: (/* @__PURE__ */ new Date()).toISOString(),
4579
+ views: [{ id: "default", name: "Table", type: "table" }]
4580
+ },
4581
+ folderPath: dbConfig.localFolder
4582
+ });
4583
+ const basePath = `${dbConfig.localFolder}/${sanitizeFileName(dbName)}.base`;
4584
+ await this.vaultFs.writeFile(basePath, baseContent);
4585
+ getLogger().debug(`[DB Sync] .base \uD30C\uC77C \uC0DD\uC131: ${basePath}`);
4586
+ } catch (error) {
4587
+ getLogger().warn(`[DB Sync] .base \uD30C\uC77C \uC0DD\uC131 \uC2E4\uD328 (\uACC4\uC18D \uC9C4\uD589):`, error);
4354
4588
  }
4355
4589
  }
4356
4590
  async pullDatabasePage(page, dbConfig) {
@@ -4370,7 +4604,7 @@ var DatabaseSyncer = class {
4370
4604
  );
4371
4605
  const localUrlMatch = coverResult.content.match(/!\[cover\]\((.+?)\)/);
4372
4606
  if (localUrlMatch?.[1]) {
4373
- properties.cover = localUrlMatch[1];
4607
+ properties.cover = `[[${localUrlMatch[1]}]]`;
4374
4608
  } else {
4375
4609
  properties.cover = cover.url;
4376
4610
  }
@@ -5990,7 +6224,7 @@ var NodeVaultFS = class {
5990
6224
  if (this.isExcluded(relativePath)) continue;
5991
6225
  if (entry.isDirectory()) {
5992
6226
  await this.walkDirNonMd(fullPath, result);
5993
- } else if (entry.isFile() && !entry.name.endsWith(".md")) {
6227
+ } else if (entry.isFile() && !entry.name.endsWith(".md") && !entry.name.endsWith(".base")) {
5994
6228
  const fileStat = await stat(fullPath);
5995
6229
  result.push({
5996
6230
  path: relativePath,
@@ -6871,6 +7105,6 @@ ${lines.join("\n")}
6871
7105
  }`;
6872
7106
  }
6873
7107
 
6874
- export { BlockConverter, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, ConfigManager, ConfigSchema, ConflictResolver, ConversionPipeline, DEFAULT_CONFIG, DatabaseSyncer, EmbedResolver, EntryEditor, FileHandler, FileWatcher, FrontmatterExtractor, FrontmatterGenerator, HtmlAnnotationStripper, ImageHandler, InlineDBParser, LocalImageRestorer, MathNormalizer, MentionToWikilink, NodeVaultFS, NotionBlockBuilder, NotionClient, PreserveMarkerCollector, PreserveMarkerInjector, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, StateDB, SyncOrchestrator, TreeMapper, UnsupportedBlockStripper, ViewDataProvider, WatchSyncService, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
7108
+ export { BaseFileGenerator, BlockConverter, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, ConfigManager, ConfigSchema, ConflictResolver, ConversionPipeline, DEFAULT_CONFIG, DatabaseSyncer, EmbedResolver, EntryEditor, FileHandler, FileWatcher, FrontmatterExtractor, FrontmatterGenerator, HtmlAnnotationStripper, ImageHandler, InlineDBParser, LocalImageRestorer, MathNormalizer, MentionToWikilink, NodeVaultFS, NotionBlockBuilder, NotionClient, PreserveMarkerCollector, PreserveMarkerInjector, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, StateDB, SyncOrchestrator, TreeMapper, UnsupportedBlockStripper, ViewDataProvider, WatchSyncService, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
6875
7109
  //# sourceMappingURL=index.js.map
6876
7110
  //# sourceMappingURL=index.js.map